<template>
  <div class="ebook-reader">
    <div id="read"></div>
    <div class="ebook-reader-mask"
         @click="onMaskClick"
         @touchmove="move"
         @touchend="moveEnd"
    ></div>
  </div>
</template>

<script>
import Epub from 'epubjs'
import {ebookMixin} from "@/utils/mixin";
import {getFontFamily, getFontSize, getTheme, saveFontFamily, saveFontSize, saveTheme, getLocation} from "@/utils/localStorage";
import {flatten} from "@/utils/book";

global.ePub = Epub
export default {
  name: "EbookReader",
  mixins: [ebookMixin],
  methods: {
    move(e){
      let offsetY = 0
      if (this.firstOffsetY){
        offsetY = e.changedTouches[0].clientY - this.firstOffsetY
        this.setOffsetY(offsetY)
      }else {
        this.firstOffsetY = e.changedTouches[0].clientY
      }
      e.preventDefault();
      e.stopPropagation();
    },
    moveEnd(e){
      this.setOffsetY(0)
      this.firstOffsetY = null
    },
    onMaskClick(e){
      let offsetX = e.offsetX
      if (offsetX > 0 && offsetX < window.innerWidth * 0.3){
        this.prevPage()
      }else if (offsetX > 0 && offsetX > window.innerWidth * 0.7){
        this.nextPage()
      }else {
        this.showTitleAndMenu();
      }
    },
    prevPage() {
      if (this.rendition) {
        this.rendition.prev().then(() => {
          this.refreshLocation()
        })
        this.hideTitleAndMenu()
      }
    },
    nextPage() {
      if (this.rendition) {
        this.rendition.next().then(() => {
          this.refreshLocation()
        })
        this.hideTitleAndMenu()
      }
    },
    showTitleAndMenu() {
      if (this.menuVisible){
        this.setSettingVisible(-1)
        this.setFontFamilyVisible(false)
      }
      this.setMenuVisible(!this.menuVisible)
    },
    initFontSize(){
      let fontSize = getFontSize(this.fileName)
      if (!fontSize){
        saveFontSize(this.fileName, this.defaultFontSize)
      }else {
        this.rendition.themes.fontSize(fontSize)
        this.setDefaultFontSize(fontSize)}
    },
    initFontFamily(){
      let font = getFontFamily(this.fileName)
      if (!font){
        saveFontFamily(this.fileName, this.defaultFontFamily)
      }else {
        this.rendition.themes.font(font)
        this.setDefaultFontFamily(font)
      }
    },
    initTheme(){
      let defaultTheme = getTheme(this.fileName)
      if (!defaultTheme) {
        defaultTheme = this.themeList[0].name
        saveTheme(this.fileName, defaultTheme)
      }
      this.setDefaultTheme(defaultTheme)
      this.themeList.forEach(theme => {
        this.rendition.themes.register(theme.name, theme.style)
      })
      this.rendition.themes.select(defaultTheme)

    },
    initRendition(){
      this.rendition = this.book.renderTo('read', {
        width: innerWidth,
        height: innerHeight,
        method: 'default'
      })
      const location = getLocation(this.fileName)
        this.display(location, ()=> {
          this.initTheme()
          this.initFontSize()
          this.initFontFamily()
          this.initGlobalStyle()
        })
      this.rendition.hooks.content.register(contents => {
        Promise.all([
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/daysOne.css`),
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/cabin.css`),
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/montserrat.css`),
          contents.addStylesheet(`${process.env.VUE_APP_RES_URL}/fonts/tangerine.css`),
        ]).then(() => {})
      })
    },
    initGesture(){
      this.rendition.on('touchstart', event => {
        this.touchStartX = event.changedTouches[0].clientX
        this.timeStartTime = event.timeStamp
      })
      this.rendition.on('touchend', event => {
        const offsetX = event.changedTouches[0].clientX - this.touchStartX
        const time = event.timeStamp - this.timeStartTime
        if (time < 500 && offsetX < -40) {
          this.nextPage()
        } else if (time < 500 && offsetX > 40) {
          this.prevPage()
        } else {
          this.showTitleAndMenu()
        }
        event.preventDefault()
        event.stopPropagation()
      })
    },
    parseBook(){
      this.book.loaded.cover.then(cover => {
        this.book.archive.createUrl(cover).then(url => {
          this.setCover(url)
        })
      })
      this.book.loaded.metadata.then(metadata => {
        this.setMetadata(metadata)
      })
      this.book.loaded.navigation.then(nav => {
        const navItem = flatten(nav.toc)
        function find(item, level = 0) {
          return !item.parent ? level : find(navItem.filter(parentItem => parentItem.id === item.parent)[0], ++level)
        }
        navItem.forEach(item => {
          item.level = find(item)
        })
        this.setNavigation(navItem)
      })
    },
    initEpub() {
      const baseUrl = `${process.env.VUE_APP_RES_URL}/epub/${this.fileName}.epub`
      this.book = new Epub(baseUrl)
      this.setCurrentBook(this.book)
      this.initRendition()
      this.initGesture()
      this.parseBook()
      this.book.ready.then(() => {
        return this.book.locations.generate(750 * (window.innerWidth / 375) * (getFontSize(this.fileName) / 16))
      }).then(locations => {
        this.setBookAvailable(true)
        this.refreshLocation()
      })
    }
  },
  mounted() {
    const fileName = this.$route.params.fileName.split('|').join('/')
    this.setFileName(fileName).then(() => {
      this.initEpub()
    })
  }
}
</script>

<style scoped lang="scss">
@import '~@/assets/styles/global.scss';
.ebook-reader {
  width: 100%;
  height: 100%;
  overflow: hidden;
  .ebook-reader-mask {
    position: absolute;
    top: 0;
    left: 0;
    background: transparent;
    z-index: 150;
    width: 100%;
    height: 100%;
  }
}
</style>
